﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2022 kingerrobot
// 版权所有。 
//
// 文件名：TaskImpl
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2022/1/26 16:49:20
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion

using KingerRobot.MexicoSailunMDC.Dao;
using System;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunMDC.SpiService;

public class PositionImpl : IPositionService
{

    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IWmsSetting _WmsSetting = new BWmsSetting();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IWcsAsrsCrnInput _WcsAsrsCrnInput = new BWcsAsrsCrnInput();
    private readonly static IWarehousingBeforeCrnService _WarehousingBeforeCrnService = new WarehousingBeforeCrnImpl();
    private readonly static IWcsAsrsCrnAbnormalOutPut _WcsAsrsCrnAbnormalOutPut = new BWcsAsrsCrnAbnormalOutPut();
    private readonly static IRcsEquipCrn _RcsEquipCrn = new BRcsEquipCrn();
    private readonly static IWcsNetAbnormal _WcsNetAbnormal = new BWcsNetAbnormal();

    public int UpdateRcsLocationIsTaskNo(long locId, int taskNo)
    {
        //添加库位绑定数据清除，任务号为0清除库位绑定数据，查询不到任务创建异常数据
        if (taskNo == 0)
        {
            WriteLog($"-1：任务流水号{taskNo},执行清空.");
            return _RcsLocation.ClearLocationHasTask(locId);
        }

        var task = _Task.GetTaskByTaskNo(taskNo);
        if (task == null)
        {
            //OLDTODO 如果task查不到，修改loc位置WcsLocSku绑定关系，RcsLoc
            WriteLog($"-2：{taskNo},任务不存在.");
            return 0;
        }

        var startLoc = task.TargetLoc.GetValueOrDefault();
        if (startLoc != locId && task.TaskType == (int)EnumTaskType.Transportation)
        {
            var taskId = task.Id.GetValueOrDefault();
            var remark = task.RemarkMemo;
            var skuId = task.SkuId.GetValueOrDefault();
            var productCode = _ProdProduct.GetCodeBySkuId(skuId);
            _Task.UpdateTaskRemark(taskId, $"{remark} | 支线口选错:原:{startLoc},实际:{locId},流水号:{taskNo},条码:{productCode}");
        }

        // 清空已绑定 TaskId 货位
        _RcsLocation.ClearLocationHasTaskByTaskId(task.Id.GetValueOrDefault());

        var result = _RcsLocation.UpdateLocationHasTask(locId,
            task.Id.GetValueOrDefault(),
            task.SkuId.GetValueOrDefault()
            );
        WriteLog($"-4：位置修改绑定返回值{result}.");
        return result;
    }

    public int UpdateRcsLocationIsProductCode(long locId, string productCode, int taskNo, bool isDeleteLoc = false)
    {
        //添加库位绑定数据清除，任务号为0清除库位绑定数据，查询不到任务创建异常数据
        WriteLog($"任务{taskNo}开始执行绑定111");
        if (string.IsNullOrWhiteSpace(productCode))
        {
            return _RcsLocation.ClearLocationHasTask(locId);
        }
        WriteLog($"任务{taskNo}开始执行绑定222");
        //var task = _Task.GetTaskByTaskNo(taskNo);
        var task = _Task.GetTaskByProductCode(productCode);
        WriteLog($"任务{taskNo}开始执行绑定333");
        //if (task is not null && task.IsSecNoread == 1)
        //{
        //    WriteLog($"任务{taskNo}开始执行绑定111");
        //    // 修改状态
        //    _Task.UpdateTaskAndCmdStatus(locId, task.Id ?? 0, (int)EnumTaskStatus.Finish);
        //    _Task.BakAndDeleteTaskAndCmd(task.Id ?? 0);
        //    task = null;
        //}

        //var crnInPut = _WcsAsrsCrnInput.GetWcsAsrsCrnInputByLoc(locId);
        var wcsAsrsCrnInput = _WcsAsrsCrnInput.GetWcsAsrsCrnInputByLoc(locId);
        WriteLog($"任务{taskNo}开始执行绑定444,wcsAsrsCrnInput{wcsAsrsCrnInput.TaskCount}");
        if (wcsAsrsCrnInput is not null && task is null)
        {
            //OLDTODO 如果task查不到，修改loc位置WcsLocSku绑定关系，RcsLoc

            var skuId = _ProdProduct.GetSkuIdByCode(productCode);

            //判断库里时打开
            //var locs = _RcsLocation.GetAllLocationsByType((int)EnumLocType.Location);
            //var wcsSkuLoc = _WcsLocSku.GetWcsLocSkusBySkuId(skuId);
            //var hasLocs = locs.Join(wcsSkuLoc, f => f.Id, s => s.LocId, (f, s) => new
            //{
            //    LocId = f.Id
            //}).ToList();
            ////如果已经在库里 
            //if (hasLocs is not null && hasLocs.Any())
            //{
            //    WriteLog($"-5：条码 {productCode},已在库中存在.");
            //    return -5;
            //}
            //如果是没有任务的胎 1 生成出库口任务 2 绑定信息 3 在quarzt里生成到出库口的指令
            if (productCode != ConstFields.Default && productCode != ConstFields.NoRead && taskNo != 0)
            {
                //只生成任务 不生成指令
                //判断当前库位index
                //var crnInPut = _WcsAsrsCrnInput.GetWcsAsrsCrnInputByLoc(locId);
                //if (crnInPut is null)
                //{
                //    WriteLog($"-3：取货位 {locId},不存在.");
                //    return 0;
                //}
                var locCrnId = wcsAsrsCrnInput.CrnId;
                var locIndex = wcsAsrsCrnInput.InputLoc1 == locId ? 1 : 2;


                //送到线体异常口
                var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(locCrnId ?? 0);
                if (abnormal is null)
                {
                    WriteLog($"-4：线体异常口 {locId},不存在.");
                    return -4;
                }
                var crnFork = _RcsEquipCrn.GetRcsEquipCrnById(locCrnId ?? 0).FirstOrDefault();
                if (crnFork is null)
                {
                    WriteLog($"-6：堆垛机货叉 {locCrnId},不存在.");
                    return -6;
                }
                var crnOutPutLoc = abnormal?.TargetLoc ?? 0;
                long startEquip = 0;
                if (locIndex == 1)
                {
                    startEquip = crnFork.CrnFork1 ?? 0;
                }
                else
                {
                    startEquip = crnFork.CrnFork2 ?? 0;
                }

                _Task.CreateTask(new()
                {
                    StartLoc = locId,
                    TargetLoc = crnOutPutLoc,
                    Type = (int)EnumTaskType.Transportation,
                    SkuId = skuId,
                    TaskNo = taskNo,//K8.LSF.Client.CodeValue(new DateTime(),"TaskNo").ToInt(0),
                    StartEquip = startEquip,
                    Status = (int)EnumTaskStatus.Executed,
                    Remark = $"入库取货位{locId},原条码{productCode},原流水号{taskNo},任务不存在,创建异常口任务",
                });

                // 清空已绑定 TaskId 货位
                _RcsLocation.ClearLocationHasTaskByTaskId(task.Id.GetValueOrDefault());

                var noTaskResult = _RcsLocation.UpdateLocationHasTask(locId,
                    task.Id.GetValueOrDefault(),
                    task.SkuId.GetValueOrDefault()
                    );

                // 绑定位置
                _WcsLocSku.SetWcsLocSku(locId, skuId, isDeleteLoc);
                return noTaskResult;
            }


        }




        //var wcsAsrsCrnInput = _WcsAsrsCrnInput.GetWcsAsrsCrnInputByLoc(locId);
        var locId1 = wcsAsrsCrnInput?.InputLoc1 ?? locId;
        var locId2 = wcsAsrsCrnInput?.InputLoc2 ?? locId;
        WriteLog($"任务{taskNo}开始执行绑定555");
        var targetLoc = task.TargetLoc.GetValueOrDefault();
        if ((targetLoc != locId1 && targetLoc != locId2) && task.TaskType == (int)EnumTaskType.Transportation)
        {
            var taskId = task.Id.GetValueOrDefault();
            var remark = task.RemarkMemo;
            var pTaskNo = task.TaskNo.GetValueOrDefault();
            _Task.UpdateTaskRemark(taskId, $"支线口选错:原:{targetLoc},实际:{locId},{locId1},{locId2},线体流水号:{taskNo},线体条码:{productCode},条码任务:{pTaskNo} | {remark}");
            // return 0;
        }
        WriteLog($"任务{taskNo}开始执行绑定666");

        // 清空已绑定 TaskId 货位
        _RcsLocation.ClearLocationHasTaskByTaskId(task.Id.GetValueOrDefault());
        WriteLog($"任务{taskNo}开始执行绑定777");
        var result = _RcsLocation.UpdateLocationHasTask(locId,
            task.Id.GetValueOrDefault(),
            task.SkuId.GetValueOrDefault()
            );
        WriteLog($"任务{taskNo}开始执行绑定888");
        // 绑定位置
        _WcsLocSku.SetWcsLocSku(locId, task.SkuId, isDeleteLoc);
        WriteLog($"任务{taskNo}开始执行绑定999");
        return result;
    }


    public int UpdateEmsRcsLocationIsProductCode(long locId, int taskNo)
    {
        //添加库位绑定数据清除，任务号为0清除库位绑定数据，查询不到任务创建异常数据
        WriteLog($"任务{taskNo}开始执行绑定224");
        if (taskNo == 0)
        {
            return 0;
        }
        WriteLog($"任务{taskNo}开始执行绑定229");
        //var task = _Task.GetTaskByTaskNo(taskNo);
        var task = _Task.GetTaskByTaskNo(taskNo);
        WriteLog($"任务{taskNo}开始执行绑定232");
        if (task is  null )
        {
            WriteLog($"任务{taskNo}为空");
            return 0;
        }

        WriteLog($"任务{taskNo}开始执行绑定248");

        // 清空已绑定 TaskId 货位
        _RcsLocation.ClearLocationHasTaskByTaskId(task.Id.GetValueOrDefault());
        WriteLog($"任务{taskNo}开始执行绑定252");
        var result = _RcsLocation.UpdateLocationHasTask(locId,
            task.Id.GetValueOrDefault(),
            task.SkuId.GetValueOrDefault()
            );
        WriteLog($"任务{taskNo}开始执行绑定257");
        // 绑定位置
        _WcsLocSku.SetWcsLocSku(locId, task.SkuId);
        WriteLog($"任务{taskNo}开始执行绑定260");
        return result;
    }

    public long GetRcsLocationIsProductCode(long locId, string productCode, int lineTaskNo)
    {
        //添加库位绑定数据清除，任务号为0清除库位绑定数据，查询不到任务创建异常数据
        if (string.IsNullOrWhiteSpace(productCode))
        {
            return _RcsLocation.ClearLocationHasTask(locId);
        }


        // 当前位置是否创建指令（是并且未执行返回 taskId）
        var taskCmd = _TaskCmd.GetTaskCmdByProductCode(productCode);
        if (taskCmd is null)
        {
            WriteLog($"-2：条码 {productCode},任务不存在.");
            return 0;
        }
        var startLoc = taskCmd.StartLoc.GetValueOrDefault();
        var status = taskCmd.CmdStatus.GetValueOrDefault();
        var taskId = taskCmd.TaskId.GetValueOrDefault();
        if (startLoc == locId)
        {
            if (status == (int)EnumTaskCmdStatus.Executable)
            {
                return taskId;
            }
            return -1;
        }


        // 是否等待超时
        var locatin = _RcsLocation.GetLocTaskIdByLocIdAndTaskId(taskId, locId);
        if (locatin is null)
        {
            var task = _Task.GetTaskByTaskId(taskId);
            if (task is null)
            {
                return -2;
            }
            _RcsLocation.UpdateLocationHasTask(locId,
                taskId,
                task.SkuId.GetValueOrDefault()
                );

            return -3;
        }
        var taskDateTime = locatin.TaskOccupyTime.GetValueOrDefault();
        var wmsSetting = _WmsSetting.GetWmsSettingByCode(ConstFields.SelectBranchLine);
        _ = int.TryParse(wmsSetting?.Value, out var number);
        var seconds = (DateTime.Now - taskDateTime).TotalSeconds;
        if (seconds <= number)
        {
            return -4;
        }

        // 超时创建任务
        var tId = _WarehousingBeforeCrnService.CreateTask(locId, lineTaskNo, $"等待超时:{number}秒,重选入库口");

        return tId;
    }

    public int UpdateRcsLocationBindProductCode(long locId, string productCode)
    {
        return _RcsLocation.UpdateLocationProductCode(locId, productCode);
    }

    public PositionInfo GetLocationInfo(long locId)
    {
        var location = _RcsLocation.GetLocationById(locId);
        if (location == null)
        {
            return null;
        }
        var position = new PositionInfo
        {
            Id = location.Id,
            Code = location.LocCode,
            X = location.AxisX,
            Y = location.AxisY,
            Z = location.AxisZ,
            T = location.AxisT,
            GroupId = location.GroupId,
            GroupIndex = location.GroupIndex
        };
        return position;
    }
    public PositionBean GetLocationBean(BizTaskBean bizTaskBean)
    {
        var takeLoc = bizTaskBean?.StartLoc ?? 0;
        var putLoc = bizTaskBean?.TargetLoc ?? 0;
        var taskNo = bizTaskBean?.TaskNo ?? 0;

        var take = _RcsLocation.GetLocationById(takeLoc);
        if (take is null)
        {
            return null;
        }
        var put = _RcsLocation.GetLocationById(putLoc);
        if (put is null)
        {
            return null;
        }

        var position = new PositionBean
        {

            TaskNo = taskNo,
            TakeId = take.Id,
            TakeCode = take.LocCode,
            TakeX = take.AxisX,
            TakeY = take.AxisY,
            TakeZ = take.AxisZ,
            TakeT = take.AxisT,

            NTakeX = take.NAxisX,
            NTakeY = take.NAxisY,
            NTakeZ = take.NAxisZ,
            NTakeT = take.NAxisT,

            TakeGroupId = take.GroupId,
            TakeGroupIndex = take.GroupIndex,


            PutId = put.Id,
            PutCode = put.LocCode,
            PutX = put.AxisX,
            PutY = put.AxisY,
            PutZ = put.AxisZ,
            PutT = put.AxisT,

            NPutX = put.NAxisX,
            NPutY = put.NAxisY,
            NPutZ = put.NAxisZ,
            NPutT = put.NAxisT,

            PutGroupId = put.GroupId,
            PutGroupIndex = put.GroupIndex,



        };
        return position;
    }
    public int DeleteWcsLocSkuByLoc(long locId)
    {
        return _WcsLocSku.DeleteWcsLocSkuByLoc(locId);
    }
}